package com.ruoyi.app.business.project;

import cn.hutool.core.collection.CollUtil;
import com.ruoyi.app.config.util.UserUtil;
import com.ruoyi.app.domain.project.invoice.InvoiceInfo;
import com.ruoyi.app.domain.project.invoice.InvoiceSave;
import com.ruoyi.common.core.enums.YesNoEnum;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.common.core.utils.PageUtils;
import com.ruoyi.common.core.web.page.CommonPageInfo;
import com.ruoyi.service.company.entity.CompanyEntity;
import com.ruoyi.service.company.service.CompanyService;
import com.ruoyi.service.project.entity.ProjectEntity;
import com.ruoyi.service.project.entity.ProjectSettleEntity;
import com.ruoyi.service.project.enums.ProjectStatusEnum;
import com.ruoyi.service.project.query.InvoiceQuery;
import com.ruoyi.service.project.service.ProjectService;
import com.ruoyi.service.project.service.ProjectSettleService;
import com.ruoyi.service.user.entity.UserEntity;
import com.ruoyi.service.user.service.UserService;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 作用：发票管理
 * </p>
 *
 * @author Zane
 * @since 2025-11-01 20:28
 */
@Component
public class ProjectInvoiceBusiness {

  @Resource
  private ProjectService projectService;
  @Resource
  private UserService userService;
  @Resource
  private CompanyService companyService;
  @Resource
  private ProjectSettleService projectSettleService;

  public CommonPageInfo<InvoiceInfo> listForInvoice(InvoiceQuery query) {
    final CommonPageInfo<ProjectEntity> pageInfo = PageUtils.startPage(query);
    pageInfo.initData(projectService.listForInvoice(query));
    final CommonPageInfo<InvoiceInfo> invoicePageInfo = pageInfo.convert(this::convert);
    //补充其他信息
    if (CollUtil.isNotEmpty(invoicePageInfo.getList())) {
      // 补充用户信息
      fillUserInfo(invoicePageInfo.getList());
      // 补充公司名称
      fillComInfo(invoicePageInfo.getList());
      // 补充开票金额和结算时间
      fillInvoiceInfo(invoicePageInfo.getList());
    }
    return invoicePageInfo;
  }

  private void fillInvoiceInfo(List<InvoiceInfo> invoiceList) {
    final Map<String, ProjectSettleEntity> settleMap = projectSettleService.mapByProjectIds(
        invoiceList.stream().map(InvoiceInfo::getProjectId).collect(
            Collectors.toList()));
    invoiceList.forEach(v -> {
      final ProjectSettleEntity projectSettleEntity = settleMap.get(v.getProjectId());
      if (Objects.nonNull(projectSettleEntity)) {
        v.setInvoiceAmount(projectSettleEntity.getActualDeduction())
            .setSettleTime(projectSettleEntity.getCreateTime());
      }
    });
  }

  private void fillComInfo(List<InvoiceInfo> invoiceList) {
    final Map<Long, CompanyEntity> companyMap = companyService.getMapByIds(
        invoiceList.stream().map(InvoiceInfo::getComId).collect(Collectors.toList()));
    invoiceList.forEach(v -> {
      final CompanyEntity companyEntity = companyMap.get(v.getComId());
      if (Objects.nonNull(companyEntity)) {
        v.setCompanyName(companyEntity.getComName());
      }
    });
  }

  private InvoiceInfo convert(ProjectEntity projectEntity) {
    return new InvoiceInfo()
        .setProjectId(projectEntity.getId())
        .setProjectName(projectEntity.getProjectName())
        .setComId(projectEntity.getComId())
        .setProjectBudget(projectEntity.getProjectBudget())
        .setStatus(projectEntity.getStatus())
        .setProjectLeader(projectEntity.getProjectLeader())
        .setDeliveryTime(projectEntity.getDeliveryTime())
        ;
  }

  private void fillUserInfo(List<InvoiceInfo> invoiceList) {
    final Map<Long, UserEntity> userMap = userService.userMapByIds(
        invoiceList.stream().map(InvoiceInfo::getProjectLeader).collect(Collectors.toList()));
    invoiceList.forEach(v -> {
      final UserEntity userEntity = userMap.get(v.getProjectLeader());
      if (Objects.nonNull(userEntity)) {
        v.setProjectLeaderName(userEntity.getName())
            .setProjectLeaderPhone(userEntity.getPhone());
      }
    });
  }

  public void makeInvoice(InvoiceSave invoiceSave) {
    //开票
    final ProjectEntity project = CommonUtils.requireNotNull(
        projectService.getById(invoiceSave.getProjectId()), "项目Id不合法");
    if (YesNoEnum.YES.eqCode(project.getInvoiceFlag())) {
      throw new ServiceException("项目已开票");
    }
    if (!ProjectStatusEnum.couldInvoice(project.getStatus())) {
      throw new ServiceException("项目未满足开票状态");
    }
    project.setInvoiceFlag(YesNoEnum.YES.getCode())
        .setInvoice(invoiceSave.getInvoice())
        .setInvoiceTime(LocalDateTime.now())
        .setInvoiceBy(UserUtil.getUserId())
        .setUpdateBy(UserUtil.getUserId())
        .setUpdateTime(LocalDateTime.now());
    projectService.updateById(project);
  }
}
